package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	mutexRule()     //【第n次Unlock()】 操作 happens-before 【第n+1次Lock()操作】
	rwmutexRule01() //【写锁的Unlock()】 happens-before 【后续任何的 RLock()/Lock()】
	rwmutexRule02() //【读锁的 RUnlock()】 happens-before 【后续写锁的 Lock()】
}

// mutexRule
//
//	@Description: 【第n次Unlock()】 操作 happens-before 【第n+1次Lock()操作】
func mutexRule() {

	var mu sync.Mutex
	var data int

	mu.Lock()
	go func() {
		data = 42   // 写操作
		mu.Unlock() // Unlock（happens-before 后续 Lock）
	}()

	mu.Lock() // 第 2 次 Lock（保证能看到 data=42）
	fmt.Println(data)
	mu.Unlock()
}

// rwmutexRule01
//
//	@Description: 【写锁的Unlock()】 happens-before 【后续任何的 RLock()/Lock()】
func rwmutexRule01() {
	var rwmu sync.RWMutex
	var shareData string

	rwmu.Lock()

	go func() {
		shareData = "hello" // 写操作
		rwmu.Unlock()       // 写锁释放（happens-before 后续读锁/写锁）
	}()

	rwmu.RLock()
	fmt.Println(shareData) // 读锁（保证能看到 sharedData="hello"
	rwmu.RUnlock()

	time.Sleep(1 * time.Second)
}

// rwmutexRule02
//
//	@Description: 【读锁的 RUnlock()】 happens-before 【后续写锁的 Lock()】
func rwmutexRule02() {
	var rwmu sync.RWMutex
	var shareData string = "hello"

	rwmu.RLock() // 读锁
	go func() {
		fmt.Println(shareData) // 读操作
		rwmu.RUnlock()         // 读锁释放（happens-before 后续写锁）
	}()

	rwmu.Lock() // 写锁（保证能看到之前读锁释放前的所有修改）
	shareData = "world"
	rwmu.Unlock()

	// 读锁（保证能看到 sharedData="world"）
	fmt.Println(shareData)

}
